<!-- 单图上传组件 -->
<template>
  <el-upload
    v-model="imgUrl"
    class="img-upload"
    :show-file-list="false"
    list-type="picture-card"
    :before-upload="handleBeforeUpload"
    :http-request="uploadFile"
    :style="{ width: props.size, height: props.size }"
    :accept="props.accept"
  >
    <template #default>
      <el-image v-if="imgUrl" :src="imgUrl" />

      <div v-if="imgUrl" class="img-upload__overlay">
        <el-icon class="img-upload__preview-icon" @click.stop="handlePreview">
          <ZoomIn />
        </el-icon>

        <el-icon class="img-upload__delete-icon" @click.stop="handleDelete">
          <Delete />
        </el-icon>
      </div>
      <el-icon v-else class="img-upload__add-icon">
        <Plus />
      </el-icon>
    </template>
  </el-upload>
</template>

<script setup lang="ts">
import {
  ElImageViewer,
  UploadRawFile,
  UploadRequestOptions,
} from "element-plus";
import FileAPI from "@/api/file";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  maxSize: {
    type: Number,
    default: 10, // 默认限制为 10MB
  },
  accept: {
    type: String,
    default: "",
  },
  size: {
    type: String,
    default: "150px",
  },
});

const emit = defineEmits(["update:modelValue"]);
const imgUrl = defineModel("modelValue", {
  type: String,
  required: true,
  default: "",
});

/**
 * 自定义图片上传
 *
 * @param options
 */
async function uploadFile(options: UploadRequestOptions): Promise<any> {
  const data = await FileAPI.upload(options.file);
  imgUrl.value = data.url;
}

/**
 * 限制用户上传文件的格式和大小
 */
function handleBeforeUpload(file: UploadRawFile) {
  if (file.size > props.maxSize * 1024 * 1024) {
    ElMessage.warning(`上传图片不能大于${props.maxSize}MB`);
    return false;
  }

  return true;
}

/**
 * 预览图片
 */
function handlePreview() {
  if (imgUrl.value) {
    const imageViewerApp = createApp({
      setup() {
        return () =>
          h(ElImageViewer, {
            urlList: [imgUrl.value],
            initialIndex: 0,
            onClose: () => {
              imageViewerApp.unmount();
              document.body.removeChild(container);
            },
          });
      },
    });
    const container = document.createElement("div");
    document.body.appendChild(container);
    imageViewerApp.mount(container);
  }
}

/**
 * 删除图片
 */
function handleDelete() {
  imgUrl.value = "";
}
</script>

<style scoped lang="scss">
:deep(.el-upload--picture-card) {
  /*  width: var(--el-upload-picture-card-size);
  height: var(--el-upload-picture-card-size); */
  width: 100%;
  height: 100%;
}

.img-upload {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  border: 1px var(--el-border-color) solid;
  border-radius: 5px;

  &:hover {
    border-color: var(--el-color-primary);
  }

  &__delete-icon {
    margin-left: 5px;
  }

  &__overlay {
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: #fff;
    background-color: var(--el-overlay-color-lighter);
    border-radius: 6px;
    opacity: 0;
    transition: opacity var(--el-transition-duration);

    &:hover {
      opacity: 1;
    }
  }
}
</style>
